home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
perlcl16.lha
/
perlclass1.6
/
perlclass.readme
< prev
next >
Wrap
Text File
|
1992-11-06
|
9KB
|
307 lines
For support Email to jegm@sgi.com
This is not thoroughly tested, so I would welcome bug reports for
a while! Also comments are always welcome.
The latest version of PerlClass is always available via anonymous
FTP from samadams.princeton.edu in /u/ftp/pub/pec
Thanks to Michael Golan <mg@Princeton.EDU> for making the site
available.
Introducing PerlClass
=====================
PerlClass is a c++ class library that implements my favourite Perl
constructs. Obviously I can't duplicate all the functionality, and
wouldn't need to as Perl already exists!! However I find this useful,
because it allows me to do Perl-like things in my programs.
This Code is not copyright, use as you will. The regexp code is by
Henry Spencer, see the comments for Copyright info. The only changes I
have made are to the header file, by adding a c++ prototype field.
The Class Hierarchy and member functions are:-
// functionality is that of perl unless otherwise noted
class PerlList<T>
T& operator[]
void reset()
int scalar()
T pop()
void push(T)
void push(PerlList<T>)
T shift()
int unshift(T)
int unshift(PerlList<T>)
PerlList<T> reverse()
PerlList<T> splice(offset, len, PerlList<T>)
PerlList<T> splice(offset, len)
PerlList<T> splice(offset)
PerlList<T> sort()
>>>>class PerlStringList // everything PerlList does and ...
int split(str [,pat] [,limit])
PerlString join([pat])
int m(exp, targ) // makes list of sub exp matches
PerlStringList grep(exp) // returns matches in list
class PerlString
int length()
char chop()
int index(PerlString [, offset])
int rindex(PerlString [, offset])
PerlString substr(offset [, len]) // works as lvalue as well
operator[]
operator<
operator>
operator<=
operator>=
operator==
operator!=
operator+ // concatenation (equivalent of . )
operator+= // like .=
int m(exp) // equiv to m/.../
int m(exp, PerlStringList&) // equiv to @s = m/.(..)../
int tr(exp, rep [,opts]) // equiv to tr/.../.../
int s(exp, rep [,opts]) // equiv to s/../../
Associative array and helpers
=============================
class Binar<T> // a key, value pair
T& value()
PerlString& key()
class Assoc<T> // an associateive array, loosely based on the perl one
T& operator(PerlString) // equivalent to perl $assoc{"one"} = value
Binar& operator[n] // returns n'th entry in associative array
PerlStringList keys() // returns a list of keys
PerlList<T> values() // returns a list of values
int isin(PerlString) // tests if key is in assoc array
T adelete(PerlString) // deletes given key/value
Other Classes
=============
VarString - A variable length string class, used in PerlString.
PerlListBase<T> - is the base class for PerlList and handles the
auto expanding dynamic array, optimized for
prepending and appending data.
TempString - makes a copy of a string, and can return a char *
and will free the storage when done. Something like a
cross between strsave() and alloca().
Regexp - Handles the interface to the regular expression library
being used.
Range - Simple class to maintain a range, just makes things easier.
NOTES
=====
This must be compiled with a 3.0 or greater c++ compiler that can
handle Templates and nested classes.
It has been tested on Borland c++ v3.1 and USL-based 3.0.
GCC doesn't like the Copy constructor syntax in template classes, and
gives an assert error as well.
To build:
compile perlclass.c++ and regex.c. Link in with your App.
Include perlclass.h, (and perlassoc.h if used).
> cc -c regex.c
> CC -c perlclass.c++
> CC yourapp.c++ perlclass.o regex.o -o yourapp
To test:
> CC -DTEST perltest.c++ perlclass.c++ regex.o -o perltest
> perltest > x
> diff x perlclass.v
regex.c is not an ANSI c file, so you will have to turn off prototype
checking on your ANSI c compiler (or select kr checking).
CAVEATS (known ones that is)
=======
This is not an optimised implementation, by any stretch of the
imagination. It is a quick and dirty, "but it works" one.
No "out of memory checking" is done, I thought I'd wait for
exceptions!!
I have taken a few liberties in translating the selected Perl
functionality into a class library, apologies to Larry Wall, and
anyone else this may offend. You are welcome to fix it, just tell me
how you did it.
A PerlList<T> can only contain a list of type T, it cannot, as yet,
have multiple types in the same list. (This is feasible but messy).
Assigning to an element of a PerlList that is greater than the current
length of the PerlList will expand the list as in perl, but the values
in the newly created elements will be undefined, unlike perl. Except
PerlStringList which will create empty strings. Also if <T> is a class
then the values will be whatever the default constructor creates.
Anything that you make a PerlList out of must define an operator<(),
for the sort routine. Its ok if it is a dummy.
The first index of a list is always 0. (Again this could be fixed).
Unlike Perl you can also access characters within
a PerlString using the '[]' syntax. But you must use substr() to
change them.
Note that PerlStrings cannot have embedded '\0' like perl, this
is an efficiency trade off, because '\0' as a terminator is so
ingrained in c++ and c strings.
Regular Expressions
-------------------
Regular expressions may be slightly different, I used the straight
Henry Spencer version. I'm not sure what changes Larry made to them.
(It definitely doesn't support \w \b \s \S \d \D, or global match
mode). - If someone can make Larry's regexp stuff into a stand-alone
package like the original regex stuff, then I'll use it!
The g & o options are not supported in the m() functions.
I will try to support the 'g' option for m() in a list context.
PerlStringList::m(exp, targ) and PerlString::m(exp, list) are used to
simulate $&, $0 - $9 in perl. In both cases the list gets loaded with
the subexpression matches. The 0'th element is equivalent to $& in perl
and the 1'st element is equivalent to $1 etc.
Note that in the PerlStringlist::m() member function, result lists are
appended whereas in PerlString::m(s, list) 'list' is reset first.
eg
{
PerlString s;
PerlStringList l1, l2;
s= "hello frobo goodbye";
l1.push("was here first1"); l2.push("was here first2");
s.m("(.*)frobo(.*)", l2); // Overwrites l with new list
l1.m("(.*)frobo(.*)", s); // appends l with new list
// produces this result:
// l2[0] is "hello frobo goodbye" // equiv of $&
// l2[1] is "hello " // equiv of $1
// l2[2] is " goodbye" // $2
// and
// l1[0] is "was here first"
// l1[1] is "hello frobo goodbye" // equiv of $&
// l1[2] is "hello " // $1
// l1[3] is " goodbye" // $2
// an l1.reset() preceding the l1.m() would get rid of l1[0] in the
// above example.
}
To get the exact perl semantics of the m function in a list context
you can use the global m() function as follows:-
{
PerlStringList sl;
sl = m("(..) (..)", "ab cd ef"); // sl[0] gets "ab", sl[1] gets "cd"
}
Perl expressions (s/123/$&*2/e) in a substitute command
(PerlString::s()) are obviously not done. However $& and $0-$9 are
correctly expanded and substituted.
Also remember that if you want to put a \ in the regular expression
then you must actually type \\ as the c compiler will interpret a \ for
you. What happens to things like \t is up to your compiler.
I/O
---
I/O is done using standard c++ streams. I think this is ok, although
some perl-ism maybe introduced one day.
eg to copy a text file a line at a time:-
{
ifstream fin("file1.txt");
ofstream fout("file2.txt");
PerlString si;
while(fin >> si) fout << si << endl;
}
This will read the entire file into a PerlStringList:-
{
PerlStringList l;
ifstream fin("file1.txt");
fin >> l;
}
One nifty outcome of using streams this way is the following syntax
will load a PerlStringList and PerlList<T> in a reasonably compact
way:-
{
PerlStringList slist;
strstream ss;
ss << "one\n" << "two\nthree\nfour\n";
ss >> slist; // creates a 4 element string list
strstream iss;
PerList<int> il;
iss << "1 2 3 4 5 6 7 8 9 10" << endl; // quick load an integer array
iss >> il; // creates a 10 element integer list
}
Iterators
---------
There is no iterator per-se, but all lists (including Assoc) allow
an index to step through the list one by one. So iteration can be
achieved, albeit clumsily.
eg
PerlList<int> intlist;
for(int i=0;i<inlist.scalar();i++){
cout << intlist[i];
}
foreach could be simulated with the following macro:-
#define FOREACH(var, array)\
for(int i=0;i<array.scalar() && (var=array[i], 1);i++)
eg
{
PerlList<int> fred;
int val, tot= 0;
{ // this is useful to avoid the 'i' in the macro colliding
FOREACH(val, fred){
tot += val;
}
}
}
A PerlList or PerlStringList may be used in an if statement to test
if the list is empty or not.
eg
{
PerlList<int> il;
if(il) cout << "List is not empty" << endl;
else il.push(1);
}
==========
Disclaimer
==========
This is a personal work, and SGI is not responsible for anything
contained herein.